﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DSS_XNA.Engine.Error;
using DSS_XNA.Engine.Script;

namespace DSS_XNA.Engine.Script.Statements
{
    public class If
    {
        #region Properties

        public string LeftCondition
        {
            get { return _leftCondition; }
            set { _leftCondition = value; }
        }
        private string _leftCondition = String.Empty;

        public string RightCondition
        {
            get { return _rightCondition; }
            set { _rightCondition = value; }
        }
        private string _rightCondition = String.Empty;

        public ConditionType ConditionType
        {
            get { return _conditionType; }
            set { _conditionType = value; }
        }
        private ConditionType _conditionType = ConditionType.EqualToo;

        public Script TrueClauseScript
        {
            get { return _trueClauseScript; }
            set { _trueClauseScript = value; }
        }
        private Script _trueClauseScript = null;

        public Script FalseClauseScript
        {
            get { return _falseClauseScript; }
            set { _falseClauseScript = value; }
        }
        private Script _falseClauseScript = null;

        #endregion

        #region Public Methods

        public If(ScriptManager manager)
        {
            this.TrueClauseScript = new Script(manager);
            this.FalseClauseScript = new Script(manager);
        }

        public void ReadInStatement(string statement)
        {
            statement = statement.Trim();

            if (!statement.StartsWith("if"))
                throw new DSSException(String.Format("Invalid statement passed in: {0}", statement));

            int wordCount = 0;
            string currentWord = String.Empty;
            statement += ' '; // so the loop will pick up the last word - a kind of a hack really but it works...
            bool stringFound = false;
            foreach (char c in statement)
            {
                // if we have found a string, read it in here
                if (c == '"')
                {
                    stringFound = !stringFound; // stop searching for a string if the end " is found - THIS WILL ONLY WORK IF stringFound IS INITED TO false
                }

                if (stringFound || c != ' ')
                {
                    currentWord += c;
                    continue;
                }

                if (currentWord == "if")
                {
                    currentWord = String.Empty;
                    continue;
                }

                // THIS WILL MEAN THAT YOU CANNOT HAVE ANY SUB STRINGS WITHIN A STRING - ALTHOUGH THAT WILL CRASH ANYWAYS THE SAME REASON IS DOES IN A NORMAL PROGRAMMING LANGUAGE -- SO A \" IS REQUIRED...
                currentWord = currentWord.Replace("\"", String.Empty);

                if (wordCount == 0)
                {
                    this.LeftCondition = currentWord;
                }
                else if(wordCount == 1)
                {
                    this.ConditionType = this.GetConditionType(currentWord);
                }
                else if (wordCount == 2)
                {
                    this.RightCondition = currentWord;
                }
                else
                {
                    throw new DSSException("Invalid syntax for IF statement. Too many arguments.");
                }

                currentWord = String.Empty;

                ++wordCount;
            }
        }

        /// <summary>
        /// This adds a script statement to this if statement
        /// </summary>
        /// <param name="statement">The statement to add</param>
        /// <param name="clause">Whether we are adding to the true of the false part of the if statement (the false part is always after an else statement)</param>
        public void AddScriptCommand(string statement, bool clause)
        {
            if (clause)
            {
                this.TrueClauseScript.ScriptLines.Add(statement);
            }
            else
            {
                this.FalseClauseScript.ScriptLines.Add(statement);
            }
        }

        public bool Load()
        {
            if (!this.TrueClauseScript.Load())
                return false;

            if (!this.FalseClauseScript.Load())
                return false;

            return true;
        }

        #endregion

        #region Private Methods

        private ConditionType GetConditionType(string currentWord)
        {
            currentWord = currentWord.ToLower().Trim();

            if (currentWord == ">")
            {
                return ConditionType.GreaterThan;
            }
            else if (currentWord == "<")
            {
                return ConditionType.LessThan;
            }
            else if (currentWord == "==")
            {
                return ConditionType.EqualToo;
            }
            else
            {
                throw new DSSException(String.Format("Unknown conditional type: {0}", currentWord));
            }
        }

        #endregion
    }
}
